/*
 * Copyright (c) 2017. All  rights reserved.
 * 项目名：microservice-user
 * 文件名：TokenAuthentication.java
 * Date  ：17-11-29 上午10:35
 * Author：abin
 *
 */

package com.stadium.common.config.security;

import com.stadium.common.utils.ResponseUtil;
import com.stadium.dto.SysTokenDto;
import com.stadium.service.SysTokenSV;
import com.stadium.vo.SysTokenVo;
import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import io.jsonwebtoken.Jwts;
import io.jsonwebtoken.SignatureAlgorithm;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.authentication.UsernamePasswordAuthenticationToken;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.AuthorityUtils;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.util.Date;
import java.util.List;
import java.util.UUID;

/**
 * Created by Administrator on 2017/11/14.
 */
public class TokenAuthentication {
    static final long EXPIRATIONTIME = 86_400_000; // 1天
//    static final long EXPIRATIONTIME = 1; // 1天

    static final String SECRET = "First@seven7"; // JWT密码
    static final String TOKEN_PREFIX = "Bearer"; // Token前缀
    public static final String HEADER_STRING = "Authorization";// 存放Token的Header Key


    @Autowired
    private SysTokenSV sysTokenSV;

    // JWT生成Token方法
    public String createToken(Authentication authentication) {
        //tokenId
        String tokenId = null;
        //获得url
        String[] user = authentication.getName().split(",");
        String security = getSecurity(user[0]);
        String userId = user[0];
        /*SysTokenDto tokenDb = sysTokenSV.getByUserId(userId);
        if (tokenDb == null) {
            tokenId = UUID.randomUUID().toString().replaceAll("-", "");
            SysTokenVo token = new SysTokenVo();
            token.setId(tokenId);
            token.setToken(security);
            token.setUserId(userId);
            sysTokenSV.save(token);
        } else {
            tokenId = tokenDb.getId();
            SysTokenVo sysTokenVo = new SysTokenVo();
            BeanUtils.copyProperties(tokenDb, sysTokenVo);
            sysTokenVo.setToken(security);
            sysTokenSV.update(sysTokenVo);
        }*/
        String userStr = String.valueOf(authentication.getPrincipal());
        // 生成JWT
        String JWT = Jwts.builder()
                // 保存权限（角色）
                .claim("User", userStr)
                .claim("tokenId", tokenId)
                // 有效期设置
                .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                // 签名设置
                .signWith(SignatureAlgorithm.HS512, SECRET).compact();

        // 将 JWT 写入 body
        return JWT;
    }

    // JWT验证方法
    public Authentication authToken(HttpServletRequest request, HttpServletResponse httpServletResponse) {
        httpServletResponse.setHeader("tokenStatus","0");
        // 从Header中拿到token
        String token = request.getHeader(HEADER_STRING);
        //tokenId
        String tokenId = null;
        if (token != null) {
            // JWT
            try {
                // 解析 Token
                Claims claims = Jwts.parser()
                        // 验签
                        .setSigningKey(SECRET)
                        // 去掉 Bearer
                        .parseClaimsJws(token.replace(TOKEN_PREFIX, "")).getBody();
                List<GrantedAuthority> user = AuthorityUtils
                        .commaSeparatedStringToAuthorityList((String) claims.get("User"));
                //获得url
                List<GrantedAuthority> authorities = AuthorityUtils
                        .commaSeparatedStringToAuthorityList((String) claims.get("tokenId"));
                boolean ifPermission = getPermission(authorities, request);
                tokenId = String.valueOf(authorities.get(0));
                String JWT = Jwts.builder()
                        // 保存权限（角色）
                        .claim("User", (String) claims.get("User"))
                        .claim("tokenId", tokenId)
                        // 有效期设置
                        .setExpiration(new Date(System.currentTimeMillis() + EXPIRATIONTIME))
                        // 签名设置
                        .signWith(SignatureAlgorithm.HS512, SECRET).compact();
                httpServletResponse.setHeader(HEADER_STRING, JWT);
                if (ifPermission) {
                    // 将 JWT 写入 body
                    return new UsernamePasswordAuthenticationToken(user.get(0) + "," + user.get(1) + "," + user.get(2) + "," + user.get(3), JWT);
                } else {
                    return null;
                }
            } catch (ExpiredJwtException e) {
                ResponseUtil.out(httpServletResponse, ResponseUtil.resultMap(false,401,"登录已失效，请重新登录"));
            } catch (Exception e){
                ResponseUtil.out(httpServletResponse, ResponseUtil.resultMap(false,500,"解析token错误"));
            }
        }
        return null;
    }

    /**
     * 获得Security
     *
     * @param userId
     * @return
     */
    public String getSecurity(String userId) {
        return userId;
    }

    /**
     * 校验url
     *
     * @param authorities
     * @param request
     * @return
     */
    public Boolean getPermission(List<GrantedAuthority> authorities, HttpServletRequest request) {
        return true;
    }
}
